Chapter 8. SPRITES - MOVING PICTURE BLOCKS If you wish to see a sample program which makes use of sprites, run SAMPLE9.PIL on the PILOT distribution diskette. PILOT supports the use of sprites. A sprite is a small image or picture consisting of a grid of 32 pixels across by 32 pixels up and down. Each pixel can be one of three colors or transparent. Within a PILOT program sprites can be displayed on the screen, either standing still or in motion. Sprites are stored on disk and within a PILOT program in a sprite table. A sprite table consists of eight 32 pixel by 32 pixel sprites, numbered 1 to 8. Pictorially, a sprite table can be viewed as follows: A Sprite Table +-----+-----+-----+-----+ | | | | | | 1 | 2 | 3 | 4 | | | | | | +-----+-----+-----+-----+ | | | | | | 5 | 6 | 7 | 8 | | | | | | +-----+-----+-----+-----+ Each of the boxes, numbered 1 to 8, above represents one 32 pixel by 32 pixel sprite. PILOT allows you to combine the sprites in a table in order to create larger sprites. There are several possible ways to create these combinations. The first combines two sprites to create a 32 by 64 pixel sprite. This is accomplished by simply viewing a sprite table in the following way: +-----+-----+-----+-----+ | | | | | | | 11 | | | | | + 9 + 10 +-----+-----+ | | | | | | | 12 | | | | | +-----+-----+-----+-----+ Sprites 1 and 5 can be combined and treated as a pair by referring to the combination as sprite 9. Sprites 2 and 6 can be combined as sprite 10. Sprites 3 and 4 can be combined as sprite 11. And sprites 7 and 8 can be combined as 12. You can also combine 4 sprites in the two following ways: +-----+-----+-----+-----+ | | | | | | | | | + 13 + 14 + | | | | | | | | | +-----+-----+-----+-----+ Sprite 13 is a combination of sprites 1,2,5 and 6. Sprite 14 is a combination of sprites 3,4,7 and 8. +-----+-----+-----+-----+ | | | 15 | | | +-----+-----+-----+-----+ | | | 16 | | | +-----+-----+-----+-----+ Sprite 15 is a combination of sprites 1,2,3 and 4. Sprite 16 is a combination of sprites 5,6,7 and 8. Finally, all 8 sprites can be treated as one large sprite, numbered sprite 17. +-----+-----+-----+-----+ | | | | | | + 17 + | | | | | | +-----+-----+-----+-----+ Within one sprite table you can think of the eight sprites in any combination that makes sense for your own program. For example, you could use sprite 16 for a 128 by 32 pixel sprite, use sprite 11 for a 64 by 32 pixel sprite, and use sprites 1 and 2 for two 32 by 32 pixel sprites. On disk, a sprite table is stored in a 2048 byte file with the file suffix of .SPR. For example: ATOMS.SPR In one PILOT program you can have as many sprite tables as you need, limited only by the amount of memory you wish to set aside for sprite tables. HOW TO EDIT SPRITE TABLES The program SE, Sprite Editor, is provided to create and edit sprite tables. With SE you can: 1. Cut sprite images out of a graphics image file and paste them into a sprite table. 2. Cut sprites out of a sprite table and paste them into a graphics image file. 3. Touch up a sprite in a sprite table. 4. Create a sprite from scratch via fat bits mode 5. View any of the 17 possible sprite combinations that can be used. To run SE and use sprites, requires a color display adapter. A monochrome adapter does not support the use of sprites. You can start SE by entering the command: SE The SE program prompts you for the name of the sprite table you wish to work on. If the sprite table already exists, enter the root name of the sprite table file (without the .SPR on the end). To create a new sprite table, either enter the name of the new the sprite table file (without the .SPR on the end) or push the ENTER key. Next, SE prompts you for the name of a graphics image file. This file must be in the bit-mapped format. It could be made by GIE, the PILOT GSX: statement or another graphics creation program that saves images in bit-mapped format. Images saved in a compressed format will not load into the sprite editor. If you intend to cut sprites out of a graphic image and paste them into the sprite table, enter the name of the graphics image at this point. Be sure to enter the entire file name, including the suffix. If you do not wish to work with a graphics image, just push ENTER. Once SE has started, the top left portion of the screen displays the sprite table you are working on. The top right portion of the screen displays a help menu. If you have loaded a graphics image, part of it is displayed in the bottom portion of the screen. Note also that on the bottom left portion of the image a sprite-sized cut-out box overlays the bit-mapped image. The sprite editor is controlled by means of the various function and cursor keys. The operations you can perform are shown below. F1 - select sprite to work on Each time you push F1, the next sprite in line is selected for operation. The current sprite is indicated by a colored number under the sprite. F2 - select sprite layout Each time you push F2, the sprite layout changes. You will see the possible combinations that can be created by referring to sprites numbered 1 through 17. Notice that the cut-out box on the graphic image changes size to reflect the sprite layout and sprite number selected. F3 - copy from image to sprite F3 copies the contents of the cut-out box on the graphic image to the currently selected sprite. (If you make a mistake, you can undo the last operation by pushing the Esc key at any time.) With this feature, you can use any paint program, such as GIE or its equivalent, to create sprites, then use the F3 function in SE to cut the picture out of the graphics image and paste it into a sprite table. F4 - copy from sprite to image F4 copies the currently selected sprite to the graphic image within the cut- out box. (If you make a mistake, the Esc key can be used to undo the mistake.) Using the F4 key you can copy a sprite back to a graphic image so that you can later use a graphics editor to modify the sprite. F5 - load new sprite table When you push F5, SE prompts for the name of a sprite table. The new sprite table will be loaded over the currently loaded sprite table. When you push F5, the prompt for a table name contains the last table name you entered in brackets. If you wish to load the same table just push ENTER. Loading a new table destroys the currently loaded table in memory so be sure to save the current table first if you wish to do so. If you wish to load another table name, type the name (without the .SPR appended to the name), and push ENTER. You can precede the file name with a drive or path designation if needed. If you have made a mistake and wish to cancel the load command, push the Esc key prior to pushing ENTER. F6 - save sprite table on disk If you wish to save the sprite table without leaving the SE program, push the F6 key. SE prompts for the name of the file to be saved. If you wish to save to the file name shown in brackets, just push ENTER. If you wish to enter another file name, type it without the .SPR suffix, then push ENTER. If you wish to cancel the save operation, push the Esc key. F7 - load graphics image The F7 key loads a new graphics image for display on the bottom portion of the screen. SE prompts for the name of the image file to be loaded, showing the last supplied name in brackets. To load the same file just push ENTER. To load a different file, type the file name and push ENTER. To cancel the operation push Esc. F8 - save graphics image The F8 key saves the current graphics image on disk. To save the image to the file name shown in brackets, just push the ENTER key. To save to another file, enter the file name then push ENTER. To cancel the save operation push Esc. F9 - enter fat bits, or touch-up mode This key can be used only when a sprite number in the range 1 through 8 is selected. The selected sprite is shown in an expanded format so that individual pixels can be identified and edited. This mode can be used to create a totally new sprite from scratch or can be used to edit or touch up, a sprite created previously. See Fat Bits Mode below for more information. On combination sprites (numbers 9-17) you will have to edit one 32 by 32 pixel segment at a time. F10 - exit sprite editor The F10 key terminates processing of the SE program. If you have made any changes to the sprite table, SE prompts for the name of a file in which to save the sprite table. If you have previously given a sprite table name, the name is shown in brackets. To save to the same file name just push ENTER. To save to another file name, enter the file name and push ENTER. If there is no name shown in brackets (ie, you have not previously entered a sprite table file name), you must enter the name of a file in order to save the sprite table; just pushing ENTER in this case bypasses the save operation. To force a bypass of the save operation, push the Esc key. If the graphics image has been modified, SE prompts similarly for the name of a file to which the graphics image is to be written. If you write the graphics image to the same file name, then the original graphics image is overwritten on disk. If you wish to retain the original image then enter a different file name. If you wish to discard the loaded image then push the ESC key to bypass the save operation. ESC - undo last operation The Esc key can be used to back out of an erroneous operation. If pushed after F3 or F4, the copy operation is undone. If pushed when prompted for a file name to load or save, the load or save is canceled. ARROW KEYS - roll graphics image The four arrow keys: up, down, left and right can be used to roll the graphics image one pixel in any direction. Holding shift while pushing any of the arrow keys rolls the graphics image by 32 pixels at a time. As the image is rolled, it wraps around from the left to the right or the top to the bottom. Notice that even though part of the image is hidden behind the upper portion of the SE screen, as the image is rolled up or down, the hidden portion can be brought into view on the bottom of the screen. Using these keys, the image can be adjusted to place any desired portion within the cut- out box shown in the lower left part of the screen. FAT BITS MODE The F9 key can be used to enter fat bits mode. To use fat bits mode the currently selected sprite number must be in the range 1 to 8. F9 is ignored for higher numbered sprites. In fat bits mode, the sprite is displayed in normal size and an expanded size that shows the color of each individual pixel. Also shown is a help menu and several status indicators. To the right of the sprite is a number from 1 to 3 showing which color is presently selected for pixel setting. Next to the number is a plus sign, if stream set mode is selected, or a minus sign, if stream clear mode is selected. Also shown is a model TS:, TYPE SCREEN statement, showing the mode and background colors you would use in your PILOT program to produce the same color combinations. Within the expanded sprite, a small box-shaped cursor shows the position of the current pixel within the sprite. The sprite can be modified, pixel by pixel, through the use of the various function and cursor keys as shown here. To set or clear a pixel you can move the cursor to the desired pixel, then push F1 or F2. If you wish to set or clear several contiguous pixels, you can use stream set or stream clear modes. With either stream mode set each pixel is set or cleared immediately as the cursor is moved from one pixel to another by the arrow keys. F1 - set a pixel The F1 key sets the current pixel to the currently selected color. F1 also turns off either stream mode, if set. F2 - clear a pixel The F2 key clears the current pixel to the background color. F2 also turns off either stream mode if set. Shift F1 - stream set mode on Shift-F1 turns on stream set mode. When stream set mode is on, the cursor keys automatically set each pixel to the current color as the cursor moves from one pixel to another. Shift F2 - stream clear mode on Shift-F2 turns on stream clear mode. When stream clear mode is on, the cursor keys automatically clear each pixel to the background color as the cursor moves from one pixel to another. Shift F5 - clear entire sprite to background The shift-F5 combination erases the entire sprite to background color. F8 - change screen mode The F8 key alternates between screen modes 4 and 5. Note that the color combinations change as does the model TS: statement shown next to the sprite. This allows you to see the sprite as it will appear in your PILOT program. F10 - exit fat bits mode The F10 key returns to the SE main screen with the edited sprite placed in the sprite table. ARROWS - move pixel cursor The up, down, right and left arrow keys can be used to move the pixel cursor one space in any direction. If the stream set or stream clear mode is on, then moving the cursor also sets or clears the pixel to which the cursor moves. PLUS and MINUS - change background color The + key increments the background color. The - key decrements the background color. The possible colors are 0 through 31. Backgrounds 16 through 31 are the same as 0 through 15 except that the foreground colors are brighter. Note that as the background color changes on the screen, the model TS: statement changes to reflect the current color number. This command lets you see the sprite displayed with in the colors you will see in your PILOT program. USING SPRITES IN A PILOT PROGRAM To use sprites in a PILOT program follow these steps: 1. Use SE to create a sprite table. The sprite table is saved on a disk file, say MINE.SPR 2. In the PILOT program, create a string variable 2218 bytes longs to hold the sprite table. The following statement would work fine: D:MINE$(2218) 3. Read the sprite table from disk into the string variable via statements such as: FX:MINE.SPR FI:0,MINE$ 4. Set the screen mode to a graphics mode valid for sprites (mode 4, 5 or 6). For example: TS:M4 5. Use the Graphics statement to specify the current sprite table via: G: S MINE$ 6. Use the Graphics statement to display or move sprites on the screen. Sprites are manipulated via turtle graphics commands on the Graphics statement. The turtle graphics commands allow you to move an invisible turtle around on the screen by commands such as forward, right, left and draw. To manipulate sprites you can: 1. Draw any sprite at the current turtle location and leave it there. 2. Remove a previously drawn sprite from the screen. 3. Draw a sprite at the current turtle location and attach it to the turtle so that it is dragged around on the screen when the turtle is moved. 4. Leave a sprite on the screen, move the turtle to some other location on the screen, then return to the spot where the sprite was left to move or remove it. SPRITE DRAWING When a sprite is drawn on the screen, it is located such that the upper left pixel of the sprite is at the turtle location. If a sprite hangs off the right side of the screen, it wraps to the left side. Likewise, if the sprite hangs off the bottom of the screen, it wraps to the top of the screen. When a sprite is drawn, it is combined with the data already on the screen so that the background-colored bits in the sprite are transparent. That is, the previous display data shows through wherever the sprite pixels are not set to a color. Colored pixels in a sprite are combined with the previous display data so that when the sprite is again removed, the previous display data is restored. This means that a sprite can pass over another complex picture without changing the other picture. In mathematical terms, sprites are drawn via an exclusive or operation. This means also that drawing a sprite once in a location makes it appear, then drawing it again in the same location makes it disappear again. SPRITE COMMANDS The specific commands that affect sprites are as follows. G: S V$ Makes string variable V$ the current sprite table. V$ must have been first dimensioned at least 2218 bytes and must have been read from a sprite file as shown above. There may be any number of sprite tables in memory and you can change the current sprite table as often as necessary. G: Sn Displays (or erases) sprite number n, (n from 1 to 17). Also attaches sprite n to the turtle. G: S0 If any sprite is attached to the turtle, it is detached and left in its current location. This command insures that no sprite is attached to the turtle. G: Fn The normal forward command which moves the turtle. If a sprite is attached to the turtle, it is moved along with the turtle to the new location. When a sprite is attached to the turtle no line is drawn by the forward command. G: Rn;Ln The normal turtle right and left turn commands. These commands are used to set the direction of motion of a sprite when attached to the turtle. G: Dx,y The normal draw to pixel x,y command which, when a sprite is not attached to the turtle, draws a line to the absolute pixel named. When a sprite is attached to the turtle, no line is drawn, but the sprite is moved from the old location to the new location. G: Gx,y The move to absolute pixel command. If a sprite is attached to the turtle, it is detached and left in its present location. The turtle moves to the new location without any sprite attached. G: Jn If a sprite other than sprite n is attached to the turtle, it is detached and left in its present location. Then the turtle jumps to the location and heading, where sprite n was last left on the screen. G: Wn This command causes a wait for n 60ths of a second. It does not directly affect sprites, except that it is very useful in adjusting the speed at which sprites move. All of the above commands, as well as all other Graphic statement commands can be combined per the normal G: statement syntax. SPRITE HINTS Often sprites can be used as "little pictures", that is, as a way to display small illustrations or diagrams which do not move at all on the screen. Sometimes a sprite is an economical way to store a graphic image rather than to use an entire screen image. To make a sprite move, attach it to the turtle, then use the forward, right and left commands in a loop to move the turtle. Though a sprite can theoretically be at any pixel location, in actuality sprites are drawn at the nearest 2-pixel boundary vertically, and the nearest 4-pixel boundary horizontally. So moving a sprite in steps less than this size may not cause any visible motion. There are two ways to affect the speed of motion. The first is by adjusting the step size taken by the forward command. The larger the step, the faster the apparent motion. The second is to introduce delays into the loop which contains the forward command. The G:Wn command can be used to do this. The longer the delay at each step, the slower the apparent motion. The smoothest motion is attained by the smaller sprites (numbers 1 to 8). The larger the sprite, the more processing time it takes to display it, and the less smoothly it will appear to move. To move more than one sprite at a time, use the G:Jn command to jump back and forth between them, moving each one a small amount per iteration. To make a sprite change shape as it moves (eg. a man walking across the screen), create a series of sprites which depict the man in each position. Then as the sprite is moved via forward statements, rotate through the series of positions simultaneously. A graphics statement command sequence that performs a complex animation can be stored in a string variable and called out via the X: statement. Such a statement can be up to 256 bytes in length. SPRITE EXAMPLES SAMPLE9.PIL on the PILOT distribution diskette is a sample sprite program. Also, SAMPLE9.SPR contains a sprite table which you could copy and use for your own experimentation. The following examples assume that these statements have been executed previously in the PILOT program. These statements read the sprite table from file MYSPRITE.SPR to the string variable X$, set graphics mode, and set X$ as the current sprite table. D:X$(2218) FX:MYSPRITE.SPR FI:0,X$ TS:M4 G:SX$ Example 1: To place sprites 1, 2 and 3 at different stationary screen locations. G:G100,50;S1; G200,87;S2; G225,125;S3; S0 Example 2: To make sprite 3 appear, move it across the screen, then make it disappear. G:G0,0; S3; H90; *200(F8; W3); S3; S0 Example 3: To make sprite 3 appear, move it from the bottom of the screen to the top, then leave it stationary on the screen. G:G100,160; S3; H0; *400(F1); S0 Example 4: To make a sprite appear, then go off and do other things, then later to move the sprite to a new location and leave it there. G:G100,60; S6; S0 < go off and do other things> G:J6; D190,20; S0; Example 5: To move two sprites simultaneously. The first statement below positions each sprite at its starting position and heading. The second statement jumps back and forth between them moving each one a small amount, repeatedly. G:G10,10;S3;H180; G280,100;S4;H270; S0 G:*100(J3;F4; J4;F4; W5); S0 Example 6: move a sprite in a circle G:S7; *40(F10;R9;W1) Example 7: move a sprite and change the shape as it moves. This example assumes that sprites 1 and 2 have been created to show a man walking with arms and legs in two different positions. G:*20(S1;W5;F4;S1;S0; S2;W5;F4;S2;S0)